package api

import (
	"fmt"
	"github.com/Shopify/sarama"
	"github.com/kataras/iris/v12"
	"github.com/satori/go.uuid"
	"ir/core/db"
	"ir/models/tables"
	"ir/services"
	"ir/utils"
	"ir/utils/response"
	"log"
	"math/rand"
	"runtime"
	"strconv"
	"time"
)

func Bar(ctx iris.Context) {
	ip := utils.GetIp(ctx.Request())
	ipInfo, _ := utils.GetIpInfo(ip)
	resp := response.New(ctx)
	resp.SetData(map[string]interface{}{
		"ip":     ip,
		"ipInfo": ipInfo,
	}).Success()
	return
}

func Test(ctx iris.Context) {
	n := 0
	runtime.GOMAXPROCS(4)
	for {
		n++
		if n > 100 {
			break
		}
		go func(n int) {
			reply, _ := db.GetRedis().Do("publish", "test", n)
			log.Println("publish reply", reply, n)
		}(n)
	}
	resp := response.New(ctx)
	resp.Success()
	return
}

func pub(i int) {
	rc := db.GetRedis()
	rc.Do("publish", "test", i)
}

// SubPub 测试redis pubsub 并发
func SubPub(ctx iris.Context) {
	for i := 0; i < 10; i++ {
		log.Println("#", i)
		go pub(i)
	}

	resp := response.New(ctx)
	resp.Success()
	return
}

func GetListOne(ctx iris.Context) {
	conn := db.GetRedis()
	reply, err := conn.Do("lindex", "lo-3-btcusdt", 0)
	if reply != nil {
		log.Println(string(reply.([]byte)), err)
	}
	response.New(ctx).Success()
	return
}

func RedisPublish(ctx iris.Context) {
	val := ctx.FormValue("val")
	conn := db.GetRedis()

	_, err := conn.Do("Publish", "buy", val)
	if err != nil {
		fmt.Println("发布错误", err)
		return
	}

	resp := response.New(ctx)
	resp.Success()
}

func randOrder() (orderBook tables.OrderBook) {
	sn := uuid.NewV4().String()
	iAccountId := utils.RandInt(1, 10)
	iAmount := utils.RandInt(1, 1000)
	accountId := strconv.Itoa(iAccountId)
	amount := strconv.Itoa(iAmount)
	symbol := "pear"
	iSide := utils.RandInt(1, 2)
	var price string
	if iSide == 1 {
		price = "10"
	} else {
		price = "9"
	}
	//iPrice := utils.RandInt(1, 10)
	//price := strconv.Itoa(iPrice)
	iNow := time.Now().UnixNano()
	ip := ""
	orderBook = tables.OrderBook{
		Sn:      sn,
		UserId:  accountId,
		Price:   price,
		Amount:  amount,
		Total:   amount,
		Symbol:  symbol,
		Side:    iSide,
		Created: iNow,
		Ip:      ip,
	}
	return
}

func MatchTest(ctx iris.Context) {
	iStartTs := time.Now().Unix()
	runtime.GOMAXPROCS(4)
	rand.Seed(time.Now().UnixNano())

	cnt := 0
	for {
		iNowTs := time.Now().Unix()
		passedSecond := iNowTs - iStartTs
		log.Println("passed second", passedSecond)
		if passedSecond >= 10 {
			fmt.Println("####执行结束####")
			break
		}
		go func() {
			orderBook := randOrder()
			err := services.AddOrder(orderBook)
			fmt.Println(err)
		}()
		cnt++
		time.Sleep(time.Millisecond * 1000)
	}

	resp := response.New(ctx)
	resp.Success()
}

//
// Create the producer
//
func createProducer() sarama.AsyncProducer {
	config := sarama.NewConfig()
	config.Producer.Return.Successes = true
	config.Producer.Return.Errors = true
	config.Producer.RequiredAcks = sarama.WaitForAll
	brokers := []string{"localhost:9092"}
	producer, err := sarama.NewAsyncProducer(brokers, config)
	if err != nil {
		log.Fatal("Unable to connect producer to kafka server", err)
	}
	return producer
}

func TestKafka(ctx iris.Context) {
	// create the producer of trade messages
	iStartTs := time.Now().Unix()
	runtime.GOMAXPROCS(4)
	cnt := 0
	for {
		iNowTs := time.Now().Unix()
		passedSecond := iNowTs - iStartTs
		if passedSecond >= 1 {
			fmt.Println("####执行结束####")
			break
		}
		go func() {
			orderBook := randOrder()
			order, err := services.PickTradeOrderData(orderBook)
			if err != nil {
				log.Println("add order err", err)
			}
			producer := createProducer()
			producer.Input() <- &sarama.ProducerMessage{
				Topic: "orders",
				Value: sarama.StringEncoder(order.ToJSON()),
			}
		}()
		cnt++
		log.Println("passed second", passedSecond)
		time.Sleep(time.Millisecond)
	}

	log.Println("cnt", cnt)

	//for i := 0; i < 10; i++ {
	//	producer := createProducer()
	//	producer.Input() <- &sarama.ProducerMessage{
	//		Topic: "orders",
	//		Value: sarama.StringEncoder(fmt.Sprintf("testing %d", i))}
	//}

	resp := response.New(ctx)
	resp.Success()
}
